package com.ziven.common.widget.alphabet;

import androidx.annotation.NonNull;

/**
 * @author Ziven
 */
class CodeToPinyin extends AbstractToPinyin {

    @NonNull
    @Override
    public String toPinyin(char indexAlphabet) {
        if (indexAlphabet == PinyinData.CHAR_12295) {
            return PinyinData.PINYIN_12295;
        }
        int code;
        if (PinyinData.MIN_VALUE <= indexAlphabet
                && indexAlphabet <= PinyinData.MAX_VALUE
                && (code = getPinyinCode(indexAlphabet)) > 0) {
            return PinyinData.PINYIN_TABLE[code];
        }
        return String.valueOf(indexAlphabet);
    }

    private int getPinyinCode(char c) {
        int offset = c - PinyinData.MIN_VALUE;
        if (0 <= offset && offset < PinyinData.PINYIN_CODE_1_OFFSET) {
            return decodeIndex(
                    PinyinCode1.PINYIN_CODE_PADDING,
                    PinyinCode1.PINYIN_CODE,
                    offset
            );
        } else if (PinyinData.PINYIN_CODE_1_OFFSET <= offset && offset < PinyinData.PINYIN_CODE_2_OFFSET) {
            return decodeIndex(
                    PinyinCode2.PINYIN_CODE_PADDING,
                    PinyinCode2.PINYIN_CODE,
                    offset - PinyinData.PINYIN_CODE_1_OFFSET
            );
        } else {
            return decodeIndex(
                    PinyinCode3.PINYIN_CODE_PADDING,
                    PinyinCode3.PINYIN_CODE,
                    offset - PinyinData.PINYIN_CODE_2_OFFSET
            );
        }
    }

    private short decodeIndex(byte[] paddings, byte[] indexes, int offset) {
        int index1 = offset / 8;
        int index2 = offset % 8;
        short realIndex;
        realIndex = (short) (indexes[offset] & 0xff);
        if ((paddings[index1] & PinyinData.BIT_MASKS[index2]) != 0) {
            realIndex = (short) (realIndex | PinyinData.PADDING_MASK);
        }
        return realIndex;
    }
}
